package org.lex.dbq.view.template;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.lex.dbq.model.bo.DefaultDriver;
import org.lex.dbq.model.bo.DriverConfig;
import org.lex.dbq.model.bo.JdbcUrlTemplate;
import org.lex.dbq.model.bo.Variable;
import org.lex.dbq.model.jdbc.template.JdbcUrlBuilder;
import org.lex.dbq.model.service.ServiceFactory;
import org.lex.dbq.model.service.TemplateService;
import org.lex.string.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TemplateDialog extends Dialog {
	public static void main(String[] args) {
		showAdd(null);
	}

	public static void showAdd(Shell shell) {
		new TemplateDialog(shell, null).open();
	}

	public static void showEdit(Shell shell, JdbcUrlTemplate edit) {
		TemplateDialog d = new TemplateDialog(shell, edit);
		d.open();
	}

	private int columns = 1;
	JdbcUrlTemplate url = new JdbcUrlTemplate();

	// template
	private Text name = null;
	private Combo template = null;
	private Combo driverName = null;
	// variable
	VariableTable variables = null;
	private Button add = null;
	private Button remove = null;

	private Logger log = LoggerFactory.getLogger(TemplateDialog.class);

	public TemplateDialog(Shell shell, JdbcUrlTemplate edit) {
		super(shell);
		if (null != edit) {
			this.url = edit;
		}
		this.setShellStyle(SWT.MAX | SWT.RESIZE);
		this.setBlockOnOpen(true);
	}

	void selectDriver(String driverName) {
		log.debug("select driverName: " + driverName);
		template.removeAll();

		String nameText = "";
		DriverConfig dc = ServiceFactory.getDriverService().getByName(driverName);
		if (null != dc) {
			String driverClass = dc.getClassName();
			Set<DefaultDriver> set = ServiceFactory.getDefaultDriversService().getDrivers(driverClass);
			for (DefaultDriver d : set) {
				template.add(d.getUrl());
			}
			if (false == set.isEmpty()) {
				DefaultDriver first = set.iterator().next();
				template.setText(first.getUrl());
				nameText = first.getName();
			}
		}
		name.setText(nameText);
	}

	@Override
	protected void okPressed() {
		// driver
		String selectDriver = driverName.getItem(driverName.getSelectionIndex());
		DriverConfig driver = ServiceFactory.getDriverService().getByName(selectDriver);
		url.setDriver(driver);
		// name,desc, etc
		url.setName(name.getText());
		url.setTemplate(template.getText());

		TemplateService ts = ServiceFactory.getTemplateService();
		ts.add(url);
		try {
			ts.store();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		super.okPressed();
	}

	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText("Template");
		shell.setMinimumSize(375, 350);
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		GridLayout layout = new GridLayout();
		layout.makeColumnsEqualWidth = false;
		layout.numColumns = columns;

		Composite con = new Composite(parent, SWT.NONE);
		con.setLayout(layout);
		con.setLayoutData(new GridData(GridData.FILL_BOTH));

		this.createTemplateGroup(con);
		this.createVariablesGroup(con);

		template.addModifyListener(new ModifyListener() {
			@Override
			public void modifyText(ModifyEvent e) {
				String t = template.getText();
				List<Variable> vars = new JdbcUrlBuilder().parseVariables(t);
				url.getVariables().clear();
				url.getVariables().addAll(vars);
				variables.setInput(url);
			}
		});

		driverName.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				selectDriver(driverName.getText());
			}
		});

		String[] drivers = ServiceFactory.getDriverService().getAllNames().toArray(new String[0]);
		Arrays.sort(drivers);
		for (String n : drivers) {
			driverName.add(n);
		}

		int selectIndex = -1;
		String selectDriverName = null;
		if (null != url.getDriver() && false == StringUtils.isNullOrTrimEmpty(url.getDriver().getName())) {
			selectDriverName = url.getDriver().getName();
			selectIndex = driverName.indexOf(selectDriverName);
		}
		if (-1 == selectIndex && drivers.length > 0) {
			selectDriverName = drivers[0];
			selectIndex = 0;
		}
		if (-1 != selectIndex) {
			driverName.select(selectIndex);
			selectDriver(selectDriverName);
		}

		return parent;
	}

	private Group createTemplateGroup(Composite parent) {
		GridData d = null;
		d = new GridData(GridData.FILL_HORIZONTAL);
		d.verticalSpan = 1;
		d.horizontalSpan = columns;

		GridLayout layout = new GridLayout();
		layout.makeColumnsEqualWidth = false;
		layout.numColumns = 2;

		Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
		group.setText("Template");
		group.setLayoutData(d);
		group.setLayout(layout);
		{
			d = new GridData();
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			Label label = new Label(group, SWT.NONE);
			label.setText("Name");
			label.setLayoutData(d);

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.verticalSpan = 1;
			d.horizontalSpan = 1;
			name = new Text(group, SWT.BORDER);
			name.setLayoutData(d);
		}
		{
			d = new GridData();
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			Label label = new Label(group, SWT.NONE);
			label.setText("Template");
			label.setLayoutData(d);

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.verticalSpan = 1;
			d.horizontalSpan = 1;
			template = new Combo(group, SWT.NONE);
			template.setLayoutData(d);
		}
		{
			d = new GridData();
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			Label label = new Label(group, SWT.NONE);
			label.setText("Driver");
			label.setLayoutData(d);

			d = new GridData(GridData.FILL_HORIZONTAL);
			d.verticalSpan = 1;
			d.horizontalSpan = 1;
			driverName = new Combo(group, SWT.READ_ONLY);
			driverName.setLayoutData(d);
		}

		return group;
	}

	private Group createVariablesGroup(Composite parent) {
		GridData d = null;
		d = new GridData(GridData.FILL_BOTH);
		d.verticalSpan = 1;
		d.horizontalSpan = columns;

		GridLayout layout = new GridLayout();
		layout.makeColumnsEqualWidth = false;
		layout.numColumns = 2;

		Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
		group.setText("Variables");
		group.setLayoutData(d);
		group.setLayout(layout);
		{
			// variables table
			d = new GridData(GridData.FILL_BOTH);
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			variables = new VariableTable(group);
			variables.setLayoutData(d);
		}
		{
			// buttons pane
			d = new GridData(GridData.FILL_VERTICAL);
			d.verticalSpan = 1;
			d.horizontalSpan = 1;

			GridLayout buttonsLayout = new GridLayout();
			buttonsLayout.makeColumnsEqualWidth = true;
			buttonsLayout.numColumns = 1;
			buttonsLayout.marginWidth = 0;
			buttonsLayout.marginHeight = 0;

			Composite con = new Composite(group, SWT.NONE);
			con.setLayoutData(d);
			con.setLayout(buttonsLayout);
			{
				d = new GridData(GridData.FILL_HORIZONTAL);
				d.verticalSpan = 1;
				d.horizontalSpan = 1;

				add = new Button(con, SWT.PUSH);
				add.setText("Add");
				add.setLayoutData(d);
				add.addSelectionListener(new AddVarHandler(this));
			}
			{
				d = new GridData(GridData.FILL_HORIZONTAL);
				d.verticalSpan = 1;
				d.horizontalSpan = 1;

				remove = new Button(con, SWT.PUSH);
				remove.setText("Remove");
				remove.setLayoutData(d);
			}
		}

		return group;
	}
}
